package org.link.exam.ui;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

import javax.annotation.processing.FilerException;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import javax.swing.filechooser.FileNameExtensionFilter;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.link.exam.bean.Student;
import org.link.exam.util.AllData;
import org.link.exam.util.Util;


/**
 * 
 * project_name:exam
 * package_name:org.link.exam.ui
 * file_name:MainFrame.java
 * @author Link
 * create_date:2015年9月9日 下午4:40:13
 * modified_date:
 * description: 窗体类
 *
 */
public class MainFrame extends JFrame {

	private JPanel mainPane;										//主面板
	private JTextField rightField,stuField;							//答案文本框
	private JLabel rightLabel,stuLabel;								//答案标签
	private JButton sureButton,selectButton1,selectButton2;			//阅卷按钮,路径选择按钮
	private JLabel highStuLabel;									//最高分学生姓名及分数标签
	private JLabel lowStulabel;										//最低分学生姓名及分数标签
	private JLabel averageLabel;									//平均分标签
	private JLabel allLabel;										//出错题目排序标签
	private JLabel saveLabel;										//保存路径标签
	private Student student;										//学生类
	private JLabel allLabel1;										//出错题目排序标签
	
	/**
	 * Create the frame.
	 */
	public MainFrame() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(608, 580);
		mainPane = new JPanel();
		mainPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(mainPane);
		mainPane.setLayout(null);
		Util.screen(this);						//设置窗体居中
		this.setDefaultCloseOperation(3);
		this.setResizable(false);
		this.setTitle("成绩输出系统");
		
		rightLabel = new JLabel("正确答案文件路径:");
		rightLabel.setHorizontalAlignment(SwingConstants.CENTER);
		rightLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
		rightLabel.setBounds(24, 35, 148, 31);
		mainPane.add(rightLabel);
		
		rightField = new JTextField("D:/mxb_answer.xml");
		rightField.setHorizontalAlignment(SwingConstants.LEADING);
		rightField.setFont(new Font("微软雅黑", Font.PLAIN, 16));
		rightField.setBounds(182, 35, 297, 31);
		rightField.setEditable(false);
		mainPane.add(rightField);
		rightField.setColumns(10);
		
		stuLabel = new JLabel("学员答案文件夹路径:");
		stuLabel.setHorizontalAlignment(SwingConstants.CENTER);
		stuLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
		stuLabel.setBounds(24, 88, 148, 31);
		mainPane.add(stuLabel);
		
		stuField = new JTextField("E:/test/");
		stuField.setHorizontalAlignment(SwingConstants.LEADING);
		stuField.setFont(new Font("微软雅黑", Font.PLAIN, 16));
		stuField.setColumns(10);
		stuField.setBounds(182, 88, 297, 31);
		stuField.setEditable(false);
		mainPane.add(stuField);
		
		saveLabel = new JLabel("阅卷结果保存路径: D:/test/chengji.xml");
		saveLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
		saveLabel.setBounds(40, 168, 358, 31);
		mainPane.add(saveLabel);
		
		highStuLabel = new JLabel("本次考试最高分: ");
		highStuLabel.setHorizontalAlignment(SwingConstants.LEADING);
		highStuLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
		highStuLabel.setBounds(40, 314, 470, 31);
		mainPane.add(highStuLabel);
	
		lowStulabel = new JLabel("本次考试最低分: ");
		lowStulabel.setHorizontalAlignment(SwingConstants.LEADING);
		lowStulabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
		lowStulabel.setBounds(40, 355, 470, 31);
		mainPane.add(lowStulabel);
		
		averageLabel = new JLabel("本次考试平均分: ");
		averageLabel.setHorizontalAlignment(SwingConstants.LEADING);
		averageLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
		averageLabel.setBounds(40, 396, 470, 31);
		mainPane.add(averageLabel);
		
		allLabel = new JLabel("本次测试出错率前10的题目为: ");
		allLabel.setHorizontalAlignment(SwingConstants.LEADING);
		allLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
		allLabel.setBounds(40, 437, 518, 31);
		mainPane.add(allLabel);
		
		allLabel1 = new JLabel();
		allLabel1.setHorizontalAlignment(SwingConstants.LEADING);
		allLabel1.setFont(new Font("微软雅黑", Font.PLAIN, 16));
		allLabel1.setBounds(40, 479, 518, 31);
		mainPane.add(allLabel1);
		
		selectButton1 = new JButton("浏览");
		selectButton1.setFont(new Font("微软雅黑", Font.PLAIN, 16));
		selectButton1.setBounds(497, 35, 76, 31);
		mainPane.add(selectButton1);
		selectButton1.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				MainFrame.this.setVisible(false);
				JFileChooser jFileChooser = new JFileChooser();
				jFileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
				jFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
				FileNameExtensionFilter name = new FileNameExtensionFilter("xml文件", "xml");//设置只显示xml文件过滤器
				jFileChooser.setFileFilter(name);
				int num = jFileChooser.showOpenDialog(null);
				if(num == JFileChooser.APPROVE_OPTION){
					rightField.setText(jFileChooser.getSelectedFile().getAbsolutePath());
				}
			}
		});
		
		selectButton2 = new JButton("浏览");
		selectButton2.setFont(new Font("微软雅黑", Font.PLAIN, 16));
		selectButton2.setBounds(497, 88, 76, 31);
		mainPane.add(selectButton2);
		selectButton2.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				JFileChooser jFileChooser = new JFileChooser();
				jFileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
				jFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
				int num = jFileChooser.showOpenDialog(null);
				if(num == JFileChooser.APPROVE_OPTION){
					stuField.setText(jFileChooser.getSelectedFile().getAbsolutePath());
				}
				
			}
		});
		
		
		sureButton = new JButton("开始阅卷");
		sureButton.setFont(new Font("微软雅黑", Font.PLAIN, 16));
		sureButton.setBounds(171, 229, 132, 43);
		mainPane.add(sureButton);
		sureButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				sureButton.setText("阅卷中");
				File rightFile = new File(rightField.getText());//正确答案路径
				File stuFile = new File(stuField.getText());
				/**
				 * 获取解析器
				 */
				SAXReader sax = new SAXReader();
				/**
				 * 解析正确答案并放入AllData.rightanswer集合中
				 */
				try {
					Document rightDocument = sax.read(rightFile);//正确答案
					Element rightRoot = rightDocument.getRootElement();
					paraseXML(rightRoot,AllData.rightanswer);//存储正确答案
				} catch (DocumentException e1) {
					e1.printStackTrace();
				}
				/**
				 * 解析学生答案并计算出相应成绩
				 */
				File[] fileList = stuFile.listFiles();//将学生成绩遍历文档出来
				for (File file : fileList) {
					if(file.isFile()){
						try {
							Document stuDocument = sax.read(file);
							Element stuRoot = stuDocument.getRootElement();
							student = new Student();
							student.setName(stuRoot.attributeValue("name"));
							paraseXML(stuRoot,AllData.stuanswer);//存储学生答案
							for(int i = 0;i<AllData.rightanswer.size();i++){
								if(AllData.rightanswer.get(i).equalsIgnoreCase(AllData.stuanswer.get(i))){
									student.setScorce(student.getScorce()+1.5);//如果相等就加1.5分,表示正确
								}else{
									student.getErrorAnswer().add(AllData.stuanswer.get(i));//错误题答案
									student.getErrorNumber().add(i+1);//错误提题号
									AllData.errorNumber.add(i+1);//记住错误题号
									AllData.errorNum.add(i+1);//错误题号不重复
								}
							}
							AllData.stuName.add(stuRoot.attributeValue("name"));//存储学生姓名
							AllData.stuScorce.add(student.getScorce());//学生成绩集合
							AllData.students.add(student);//添加学生
							AllData.stuanswer.clear();//清空stuanswer里面的内容
						} catch (DocumentException e1) {
							e1.printStackTrace();
						}
					}
				}
				/**
				 * 保存学生成绩至指定路径
				 */
				File saveDir = new File("D:/test");//成绩保存文件夹
				File saveFile = new File(saveDir.getAbsolutePath()+File.separator+"chengji.xml");//成绩保存文件
				if(!saveDir.exists()){//创建文件夹
					saveDir.mkdir();
				}
				if(!saveFile.exists()){//创建xml文件
					try {
						saveFile.createNewFile();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
				
				/**
				 * 计算最高分,最低分,平均分
				 */
				Double[] d = AllData.stuScorce.toArray(new Double[AllData.stuScorce.size()]);
				Arrays.sort(d);//对分数数组d进行升序排序
				double lowSorce = d[0];//最低分
				double highSorce = d[d.length-1];//最高分
				double allSorce = 0.0;//总的分数
				for (Double double1 : d) {
					allSorce+=double1;
				}
				double averagSorce = allSorce/d.length;//平均分
				averageLabel.setText("本次考试平均分为: "+averagSorce+"分");
				ArrayList<Integer> lowScorceIndex = new ArrayList<Integer>();//最低分索引集合
				ArrayList<Integer> highScorceIndex = new ArrayList<Integer>();//最高分索引集合
				for(int i = 0;i<AllData.stuScorce.size();i++){
					if(AllData.stuScorce.get(i)==lowSorce){
						lowScorceIndex.add(i);
					}else if(AllData.stuScorce.get(i)==highSorce){
						highScorceIndex.add(i);
					}
					
				}
				String lowName="",highName="";
				for (Integer low : lowScorceIndex) {
					lowName = lowName.concat(AllData.stuName.get(low)+" ");//最低分学生姓名
				}
				for (Integer high : highScorceIndex) {
					highName = highName.concat(AllData.stuName.get(high)+" ");//最高分学生姓名
				}
				highStuLabel.setText("本次考试最高分数: "+highSorce+"分 , 学生姓名: "+highName);
				lowStulabel.setText("本次考试最低分数: "+lowSorce+"分 , 学生姓名: "+lowName);
				
				HashSet<Double> dNotRepeat = new HashSet<Double>();//取出经过排序后的d数组中不重复的元素从高到低排序
				for(int i = d.length-1;i>=0;i--){
					dNotRepeat.add(d[i]);
				}
				Double[] notReapeatD = dNotRepeat.toArray(new Double[dNotRepeat.size()]);
				Arrays.sort(notReapeatD);//重新排序
				
				/**
				 * 写xml文件
				 */
				int num1 = 1;
				Document document = DocumentHelper.createDocument();
				Element rootElement = DocumentHelper.createElement("学生成绩");//创建根
				document.setRootElement(rootElement);//设置根元素
				for(int i = notReapeatD.length-1;i>=0;i--){
					for(int j = 0;j<AllData.stuScorce.size();j++){
						if((notReapeatD[i]+"").equals(AllData.stuScorce.get(j)+"")){//比较两个分数元素(将double转换成字符串形式比较,用double比较会有问题)
							Element element = DocumentHelper.createElement("stu"+num1);//学生元素
							num1++;
							element.addAttribute("name",AllData.students.get(j).getName()).addAttribute("point", AllData.students.get(j).getScorce()+"");
							rootElement.add(element);
							for(int f = 0;f<AllData.students.get(j).getErrorNumber().size();f++){//存储错误题号以及对应的答案
								Element element2 = DocumentHelper.createElement("item");//错误题题号及答案元素
								element2.addAttribute("id", AllData.students.get(j).getErrorNumber().get(f)+"").setText(AllData.students.get(j).getErrorAnswer().get(f));
								element.add(element2);
							}
						}
					}
				}
				OutputFormat format = new  OutputFormat("\t", true);//\t 代表的是缩进  true：换行
				format.setEncoding("utf-8");
				try {
					XMLWriter writer = new XMLWriter(new FileOutputStream("d:/test/chengji.xml"), format);
					writer.write(document);
					writer.close();
				} catch (UnsupportedEncodingException e1) {
					e1.printStackTrace();
				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				
				/**
				 * 找出错误率较高的几道题
				 */
				ArrayList<Integer> totalError = new ArrayList<Integer>();//错误题对应的出错次数集合
				Integer[] error = AllData.errorNum.toArray(new Integer[AllData.errorNum.size()]);//将Alldata中不重复的题号转换成数组(出错题题号数组)
				for(int i = 0;i<error.length;i++){
					int num = 0;
					for(int j = 0;j<AllData.errorNumber.size();j++){
						if(error[i] == AllData.errorNumber.get(j)){
							num+=1;
						}
					}
					totalError.add(num);
				}
				ArrayList<String> errorSubjectSort = new ArrayList<String>();//错误题出错率从高到低的集合排序
				Integer[] totalErrorSort = totalError.toArray(new Integer[totalError.size()]);
				Arrays.sort(totalErrorSort);//对错误题集合进行升序排序
				HashSet<Integer> errorNotRepeat = new HashSet<Integer>();//定义数组将进行升序排序过后的totalErrorSort数组进行筛选出不重复的元素
				for (Integer integer : totalErrorSort) {
					errorNotRepeat.add(integer);
				}
				Integer[] notRepeatError = errorNotRepeat.toArray(new Integer[errorNotRepeat.size()]);//将其转换成数组形式
				Arrays.sort(notRepeatError);//排序
				for(int i = notRepeatError.length-1;i>=0;i--){
					for(int j = 0;j<totalError.size();j++){
						if(notRepeatError[i]==totalError.get(j)){
							errorSubjectSort.add(error[j]+"题("+notRepeatError[i]+"次)");
						}
					}
				}
				String label = "",label1 = "";
				for(int i = 0;i<4;i++){
					label = label.concat(errorSubjectSort.get(i)+",");//出错率前10的题目
				}
				for(int i=4;i<10;i++){
					label1 = label1.concat(errorSubjectSort.get(i)+",");
				}
				allLabel.setText("本次测试出错率前10的题目为: "+label.substring(0, label.length()-1));
				allLabel1.setText(label1.substring(0, label1.length()-1));
				AllData.errorNum.clear();
				AllData.errorNumber.clear();
				AllData.rightanswer.clear();
				AllData.stuanswer.clear();
				AllData.students.clear();
				AllData.stuName.clear();
				AllData.stuScorce.clear();
				sureButton.setText("阅卷结束");
			}
		});
	}
	/**
	 * 
	 * description: 解析xml文档
	 * 2015年9月9日 下午4:58:36
	 * @author Link
	 * void
	 *
	 */
	public void paraseXML(Element rightRoot,ArrayList<String> str){
		@SuppressWarnings("unchecked")
		List<Element> list = rightRoot.elements();
		for (Element element : list) {
			if(element.isTextOnly()){//是否只有单个元素
				str.add(element.getText());//存储每道题答案
			}else{
				paraseXML(element,str);//递归
			}
		}
	}
}
















